home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1996 #15 / Monster Media Number 15 (Monster Media)(July 1996).ISO / graphics / 3dview12.zip / 3D.CPP next >
C/C++ Source or Header  |  1996-05-28  |  14KB  |  397 lines

  1. #include <math.h>
  2. #include <i86.h>
  3.  
  4. #include "defines.hpp"
  5.  
  6. #include "3d.hpp"
  7.  
  8. _3D_Point *PointArray = new _3D_Point [1000];
  9. long PointArrayPtr = 0;
  10.  
  11. _3D_Object **Obj3DArray = new _3D_Object* [1000];
  12. long Obj3DArrayPtr = 0;
  13.  
  14. double _3D_ScreenDistance = 1;
  15.  
  16. double _3D_EyeX, _3D_EyeY , _3D_EyeZ;
  17.  
  18. double _3D_Alpha, _3D_SINAlpha, _3D_COSAlpha;
  19. double _3D_Phi, _3D_SINPhi, _3D_COSPhi, _3D_SINnPhi, _3D_COSnPhi;
  20. double _3D_Gamma, _3D_SINGamma, _3D_COSGamma, _3D_SINnGamma, _3D_COSnGamma;
  21. double _3D_Omega, _3D_SINOmega, _3D_COSOmega, _3D_SINnOmega, _3D_COSnOmega;
  22.  
  23. struct _3D_Matrix _3D_Projection_Matrix;
  24.  
  25. double _3D_MaxDistance = 1000;
  26.  
  27. long vMidX,vMidY,vMulX,vMulY;
  28.  
  29. extern void (*_3D_TexturedTriangle) ( long, long, long, long, long, long, long, long,
  30.                                      long, long, long, long, void* ) = 0;
  31. extern void (*_3D_TexturedTriangleZBuf) ( long, long, long, long, double,
  32.                                            long, long, long, long, double,
  33.                                            long, long, long, long, double, void* ) = 0;
  34. extern void (*_3D_FlatTriangle) ( long, long ,long, long, long, long, DWORD ) = 0;                                  
  35. extern void (*_3D_GouraudTriangle) ( long, long, DWORD, long, long, DWORD, long, long, DWORD ) = 0;
  36. extern DWORD (*_3D_DistColor) ( double, DWORD ) = 0;
  37. extern void (*_3D_FlatTriangleZBuf) ( long, long, double, long, long, double,
  38.                                         long, long, double, DWORD ) = 0;
  39. extern void (*_3D_GouraudTriangleZBuf) ( long, long, double, DWORD, long, long,
  40.                                            double, DWORD, long, long, double, DWORD ) = 0;                                        
  41.  
  42. void _3D_InitMatrix_Rotate( _3D_Matrix &M,
  43.                             double sinPhi, double cosPhi,
  44.                             double sinGamma, double cosGamma,
  45.                             double sinOmega, double cosOmega ) {
  46.     M.MXX =  cosPhi*cosOmega+sinPhi*sinGamma*sinOmega;
  47.     M.MXY =  sinPhi*cosOmega-cosPhi*sinGamma*sinOmega;
  48.     M.MXZ =  cosGamma*sinOmega;
  49.     M.MYX = -sinPhi*cosGamma;
  50.     M.MYY =  cosPhi*cosGamma;
  51.     M.MYZ =  sinGamma;
  52.     M.MZX = -cosPhi*sinOmega+sinPhi*sinGamma*cosOmega;
  53.     M.MZY = -sinPhi*sinOmega-cosPhi*sinGamma*cosOmega;
  54.     M.MZZ =  cosGamma*cosOmega;
  55. };
  56.  
  57. void _3D_Translate( double &X, double &Y, double &Z,
  58.                     double TX, double TY, double TZ ) {
  59.     X += TX;
  60.     Y += TY;
  61.     Z += TZ;
  62. };
  63.  
  64. void _3D_Rotate_Forward( double &X, double &Y, double &Z, _3D_Matrix M ) {
  65.     double NX,NY,NZ;
  66.     NX = X;
  67.     NY = Y;
  68.     NZ = Z;
  69.     X = M.MXX*NX + M.MXY*NY + M.MXZ*NZ;
  70.     Y = M.MYX*NX + M.MYY*NY + M.MYZ*NZ;
  71.     Z = M.MZX*NX + M.MZY*NY + M.MZZ*NZ;
  72. };
  73.  
  74. void _3D_SetEye( double X, double Y, double Z ) {
  75.     _3D_EyeX = X;
  76.     _3D_EyeY = Y;
  77.     _3D_EyeZ = Z;
  78. };
  79.  
  80. void _3D_SetEye_Globe( double MX, double MY, double MZ, double Rad ) {
  81.     _3D_SetEye( MX - Rad * _3D_SINPhi * _3D_COSGamma,
  82.                 MY - Rad * _3D_COSPhi * _3D_COSGamma,
  83.                 MZ + Rad * _3D_SINGamma );
  84. };
  85.  
  86. void _3D_SetVParams( long MidX, long MidY, long MulX, long MulY ) {
  87.     vMidX = MidX;
  88.     vMidY = MidY;
  89.     vMulX = MulX;
  90.     vMulY = MulY;
  91. };
  92.  
  93. void _3D_SetAlpha( double A ) {
  94.     _3D_Alpha = A;
  95.     _3D_SINAlpha = sin( _3D_Alpha );
  96.     _3D_COSAlpha = cos( _3D_Alpha );
  97. };
  98.  
  99. void _3D_SetPhi( double A ) {
  100.     _3D_Phi = A;
  101.     _3D_SINPhi  = sin(  _3D_Phi );
  102.     _3D_COSPhi  = cos(  _3D_Phi );
  103.     _3D_SINnPhi = sin( -_3D_Phi );
  104.     _3D_COSnPhi = cos( -_3D_Phi );
  105. };
  106.  
  107. void _3D_SetGamma( double A ) {
  108.     _3D_Gamma = A;
  109.     _3D_SINGamma  = sin(  _3D_Gamma );
  110.     _3D_COSGamma  = cos(  _3D_Gamma );
  111.     _3D_SINnGamma = sin( -_3D_Gamma );
  112.     _3D_COSnGamma = cos( -_3D_Gamma );
  113. };
  114.  
  115. void _3D_SetOmega( double A ) {
  116.     _3D_Omega = A;
  117.     _3D_SINOmega  = sin(  _3D_Omega );
  118.     _3D_COSOmega  = cos(  _3D_Omega );
  119.     _3D_SINnOmega = sin( -_3D_Omega );
  120.     _3D_COSnOmega = cos( -_3D_Omega );
  121. };
  122.  
  123. void _3D_InitRotation() {
  124.     _3D_InitMatrix_Rotate( _3D_Projection_Matrix,
  125.                            _3D_SINnPhi, _3D_COSnPhi,
  126.                            _3D_SINnGamma, _3D_COSnGamma,
  127.                            _3D_SINnOmega, _3D_COSnOmega );
  128. };
  129.  
  130. void ProjectPoint( _3D_Point &P ) {
  131.     double NX,NY,NZ;
  132.     
  133.     P.V = 1;
  134.  
  135.     NX = P.X - _3D_EyeX;
  136.     NY = P.Y - _3D_EyeY;
  137.     NZ = P.Z - _3D_EyeZ;
  138.     
  139.     P.D = sqrt( NX*NX + NY*NY + NZ*NZ );
  140.  
  141.     if ( P.D > _3D_MaxDistance ) return;
  142.  
  143.     if ( P.D == 0 ) return;
  144.  
  145.     _3D_Rotate_Forward( NX, NY, NZ, _3D_Projection_Matrix );
  146.     
  147.     if ( NY / P.D < _3D_COSAlpha ) return;
  148.  
  149.     P.V = 0;
  150.  
  151.     P.PX = vMidX + _3D_ScreenDistance * vMulX * NX / NY;
  152.     P.PY = vMidY - _3D_ScreenDistance * vMulY * NZ / NY;
  153. };
  154.  
  155. long _3D_NewPoint( double X, double Y, double Z ) {
  156.     PointArray[ PointArrayPtr ].X = X;
  157.     PointArray[ PointArrayPtr ].Y = Y;
  158.     PointArray[ PointArrayPtr ].Z = Z;
  159.     PointArrayPtr++;
  160.     return (PointArrayPtr-1);
  161. };
  162.  
  163. double _3D_Point_GetX( long P ) {
  164.     return PointArray[P].X;
  165. };
  166.  
  167. double _3D_Point_GetY( long P ) {
  168.     return PointArray[P].Y;
  169. };
  170.  
  171. double _3D_Point_GetZ( long P ) {
  172.     return PointArray[P].Z;
  173. };
  174.  
  175. void _3D_ProjectPoints( long Start, long End ) {
  176.     if ( Start == -1 )
  177.         Start = 0;
  178.     if ( End == -1 )
  179.         End = PointArrayPtr-1;
  180.     for ( int i=Start ; i <= End ; i++ ) {
  181.         ProjectPoint( PointArray[i] );
  182.     };
  183. };
  184.  
  185. void _3D_ForAllPointsDo( _3D_PointFunc P ) {
  186.     for ( int i=0; i<PointArrayPtr; i++ ) {
  187.         P(PointArray[i]);
  188.     };
  189. };
  190.  
  191. void _3D_RotatePointsForward( long Start, long End,
  192.                               double MX, double MY, double MZ, _3D_Matrix M ) {
  193.     for ( long i = Start; i <= End ; i++ ) {
  194.         _3D_Translate( PointArray[i].X, PointArray[i].Y, PointArray[i].Z, -MX, -MY, -MZ );                           
  195.         _3D_Rotate_Forward( PointArray[i].X,
  196.                             PointArray[i].Y,
  197.                             PointArray[i].Z, M );
  198.         _3D_Translate( PointArray[i].X, PointArray[i].Y, PointArray[i].Z, MX, MY, MZ );                           
  199.     };
  200. };
  201.  
  202. void _3D_NewObject( _3D_Object *O ) {
  203.     Obj3DArray[ Obj3DArrayPtr ] = O;
  204.     Obj3DArrayPtr++;
  205. };
  206.  
  207. void _3D_DrawObjects() {
  208.     for ( int i=0; i < Obj3DArrayPtr; i++ ) {
  209.         (*Obj3DArray[i]).Draw();
  210.     };
  211. };
  212.  
  213. void _3D_PrepareObjects() {
  214.     for ( int i=0; i < Obj3DArrayPtr; i++ ) {
  215.         (*Obj3DArray[i]).PrepareDraw();
  216.     };
  217. };
  218.  
  219. void _3D_SortObjects() {
  220.     for( long a = 0; a < Obj3DArrayPtr-1; a++ ) {
  221.         long MaxDObj = a;
  222.         for( long b = a+1; b < Obj3DArrayPtr; b++ ) {
  223.             if ( (*Obj3DArray[b]).D > (*Obj3DArray[MaxDObj]).D )
  224.                 MaxDObj = b;
  225.         };
  226.         _3D_Object* M = Obj3DArray[a];
  227.         Obj3DArray[a] = Obj3DArray[MaxDObj];
  228.         Obj3DArray[MaxDObj] = M;
  229.     };
  230. };
  231.  
  232. void _3D_SortObjectsZ() {
  233.     for( long a = 0; a < Obj3DArrayPtr-1; a++ ) {
  234.         long MinDObj = a;
  235.         for( long b = a+1; b < Obj3DArrayPtr; b++ ) {
  236.             if ( (*Obj3DArray[b]).D < (*Obj3DArray[MinDObj]).D )
  237.                 MinDObj = b;
  238.         };
  239.         _3D_Object* M = Obj3DArray[a];
  240.         Obj3DArray[a] = Obj3DArray[MinDObj];
  241.         Obj3DArray[MinDObj] = M;
  242.     };
  243. };
  244.  
  245. void _3D_Normal( double AX, double AY, double AZ, double BX, double BY, double BZ,
  246.              double &NX, double &NY, double &NZ ) {
  247.     NX = AY*BZ-AZ*BY;
  248.     NY = AZ*BX-AX*BZ;
  249.     NZ = AX*BY-AY*BX;
  250. };
  251.  
  252. _3D_Triangle::_3D_Triangle( long P1, long P2, long P3, DWORD C, _3D_Triangle_SideTyp S,
  253.                             _3D_Triangle_MidPointTyp M,_3D_Triangle_Typ T ) {
  254.     PA = P1;
  255.     PB = P2;
  256.     PC = P3;
  257.     Color = C;
  258.     TriangleTyp = T;
  259.     SideTyp = S;
  260.     MidPointTyp = M;
  261.     CalcNormal();
  262.     CalcMidPoint();
  263.     CommonInit();
  264. };
  265.  
  266. _3D_Triangle::_3D_Triangle( long P1, long tx1, long ty1,
  267.                             long P2, long tx2, long ty2,
  268.                             long P3, long tx3, long ty3, void *T,
  269.                             _3D_Triangle_SideTyp S, _3D_Triangle_MidPointTyp M,
  270.                             _3D_Triangle_Typ TYP ){
  271.     PA = P1;
  272.     PB = P2;
  273.     PC = P3;
  274.     Texture = T;
  275.     TriangleTyp = TYP;
  276.     SideTyp = S;
  277.     MidPointTyp = M;
  278.     TXA = tx1; TYA = ty1;
  279.     TXB = tx2; TYB = ty2;
  280.     TXC = tx3; TYC = ty3;
  281.     CalcNormal();
  282.     CalcMidPoint();
  283.     CommonInit();
  284. };
  285.  
  286. void _3D_Triangle::CommonInit() {
  287.     if ( TriangleTyp == FlatShadedZBuf )
  288.         CalcDistance = False;
  289.     else
  290.         CalcDistance = True;
  291.     CalcDistance = True;
  292. };
  293.  
  294. void _3D_Triangle::CalcMidPoint() {
  295.     switch ( MidPointTyp ) {
  296.         case Average :
  297.             MX = (PointArray[PA].X + PointArray[PB].X + PointArray[PC].X ) / 3;
  298.             MY = (PointArray[PA].Y + PointArray[PB].Y + PointArray[PC].Y ) / 3;
  299.             MZ = (PointArray[PA].Z + PointArray[PB].Z + PointArray[PC].Z ) / 3;
  300.             break;
  301.         case Rectangle:
  302.             MX = ( PointArray[PA].X + PointArray[PC].X ) / 2;
  303.             MY = ( PointArray[PA].Y + PointArray[PC].Y ) / 2;
  304.             MZ = ( PointArray[PA].Z + PointArray[PC].Z ) / 2;
  305.             break;
  306.         case RectFourTri:
  307.             MX = PointArray[PC].X;
  308.             MY = PointArray[PC].Y;
  309.             MZ = PointArray[PC].Z;
  310.             break;
  311.     };
  312. };
  313.  
  314. void _3D_Triangle::CalcNormal() {
  315.     _3D_Normal( PointArray[PB].X - PointArray[PA].X,
  316.                 PointArray[PB].Y - PointArray[PA].Y,
  317.                 PointArray[PB].Z - PointArray[PA].Z,
  318.                 PointArray[PC].X - PointArray[PA].X,
  319.                 PointArray[PC].Y - PointArray[PA].Y,
  320.                 PointArray[PC].Z - PointArray[PA].Z,
  321.                 NX,NY,NZ);
  322. };
  323.  
  324. void _3D_Triangle::PrepareDraw() {
  325.     double RX, RY, RZ;
  326.     CalcNormal();
  327.     RX = MX - _3D_EyeX;
  328.     RY = MY - _3D_EyeY;
  329.     RZ = MZ - _3D_EyeZ;
  330.     V = 0;
  331.     if ( CalcDistance == True )
  332.         D = sqrt( RX*RX + RY*RY + RZ*RZ );
  333.     if ( SideTyp == Singlesided )
  334.         if ( RX*NX + RY*NY + RZ*NZ < 0 )
  335.             V = 1;
  336.     V += char( PointArray[PA].V + PointArray[PB].V + PointArray[PC].V );
  337. };
  338.  
  339. void _3D_Triangle::Draw() {
  340.     if ( V==0 ) {
  341.         switch ( TriangleTyp ) {
  342.             case FlatShaded:                    
  343.                 _3D_FlatTriangle( PointArray[PA].PX, PointArray[PA].PY,
  344.                                   PointArray[PB].PX, PointArray[PB].PY,
  345.                                   PointArray[PC].PX, PointArray[PC].PY,
  346.                                   _3D_DistColor( D, Color ) );
  347.                 break;
  348.             case GouraudShaded:                           
  349.                 _3D_GouraudTriangle( PointArray[PA].PX, PointArray[PA].PY,
  350.                                      _3D_DistColor(PointArray[PA].D,Color),
  351.                                      PointArray[PB].PX, PointArray[PB].PY,
  352.                                      _3D_DistColor(PointArray[PB].D,Color),
  353.                                      PointArray[PC].PX, PointArray[PC].PY,
  354.                                      _3D_DistColor(PointArray[PC].D,Color) );
  355.                 break;
  356.             case Textured:
  357.                 _3D_TexturedTriangle( PointArray[PA].PX, PointArray[PA].PY,
  358.                                       TXA, TYA,
  359.                                       PointArray[PB].PX, PointArray[PB].PY,
  360.                                       TXB, TYB, 
  361.                                       PointArray[PC].PX, PointArray[PC].PY,
  362.                                       TXC, TYC, Texture );
  363.                 break;
  364.             case FlatShadedZBuf:
  365.                 _3D_FlatTriangleZBuf( PointArray[PA].PX, PointArray[PA].PY,
  366.                                       PointArray[PA].D,
  367.                                       PointArray[PB].PX, PointArray[PB].PY,
  368.                                       PointArray[PB].D,
  369.                                       PointArray[PC].PX, PointArray[PC].PY,
  370.                                       PointArray[PC].D, _3D_DistColor( D, Color ) );
  371.                 break;
  372.             case GouraudShadedZBuf:
  373.                 _3D_GouraudTriangleZBuf( PointArray[PA].PX, PointArray[PA].PY,
  374.                                          PointArray[PA].D,
  375.                                          _3D_DistColor( PointArray[PA].D, Color ),
  376.                                          PointArray[PB].PX, PointArray[PB].PY,
  377.                                          PointArray[PB].D,
  378.                                          _3D_DistColor( PointArray[PB].D, Color ),
  379.                                          PointArray[PC].PX, PointArray[PC].PY,
  380.                                          PointArray[PC].D, 
  381.                                          _3D_DistColor( PointArray[PC].D, Color ) );
  382.                 break;
  383.             case TexturedZBuf:
  384.                 _3D_TexturedTriangleZBuf( PointArray[PA].PX, PointArray[PA].PY,
  385.                                           TXA, TYA,
  386.                                           PointArray[PA].D,
  387.                                           PointArray[PB].PX, PointArray[PB].PY,
  388.                                           TXB, TYB, 
  389.                                           PointArray[PB].D,
  390.                                           PointArray[PC].PX, PointArray[PC].PY,
  391.                                           TXC, TYC, 
  392.                                           PointArray[PC].D, Texture );
  393.                 break;
  394.         };
  395.     };
  396. };
  397.